'''
森林大火模拟扩散。
将最左侧的网格作为火线，每个单元格着火时可以扩散到八个邻居。
没有使用其他辅助变量，直接使用的颜色作为标签进行判断：
绿色——树木；白色——空地；红色——着火；黑色——灰烬。

作者：侯展意
协议：木兰2.0
'''

import random
import takagiabm as tak  # 这是第一种导入的方式。其他示例中还有另一种导入风格，可以按照喜好选用。
def modelSetup(model):
    global density
    for x in range(model.width):
        for y in range(model.height):

            a = (x, y)

            if (random.random() > 1 - density.value):  # 将50%的单元格设置为生.其余可自行定义.

                model.grid.getCellByPos(a).setColor(tak.green)  # 导入颜色.
            else:
                model.grid.getCellByPos(a).setColor(tak.white)  # 设置为黑色.
    for y in range(model.height):
        if(model.grid.getCellByPos((0,y)).getColor()==tak.green):
            model.grid.getCellByPos((0,y)).setColor(tak.red)

def ifNeighborBurning(neighbors=[]):  # 在外部定义函数也是可以的！
    for n in neighbors:
        if (n.getColor() == tak.red):
            return True
    return False


def cellStep(cell):
    global usegreen
    neighbors = cell.getNeighbors()  # 获取八个邻居
    burning=ifNeighborBurning(neighbors)
    color=cell.getColor()
    if(color==tak.red):
        cell.setColorLater(tak.black)# 烧毁，设置颜色为黑色
    elif color==tak.green:
        if(burning==True):
            cell.setColorLater(tak.red)# 如果邻居有火就开始燃烧。


density = tak.Var('森林密度', 0.2, range=(0, 0.01, 1))  # min,max,step，最小，最大和步长。
varList = [density]
tak.DiscreteGridModel = tak.prepareModel(modelClass=tak.DiscreteGridModel, varList=varList,
                                         agentActivationPolicy='none', cellActivationPolicy='casual',
                                         modelInitFunc=modelSetup, width=100, height=100,wrapPolicy='box')
tak.DiscreteGridCell = tak.prepareCell(tak.DiscreteGridCell, cellStep)

if __name__ == "__main__":
    tak.simStart(__file__, tak.DiscreteGridModel, noGUI=False, maxSteps=100)  # maxsteps只有在noGUI=True的时候才有效。
    # 图形界面启动时，仿真步数没有限制。
